gusucode.com > VC++ EMF图片浏览器(可读emf、wmf、emz、wmz、png……等)-源码程序 > VC++ EMF图片浏览器(可读emf、wmf、emz、wmz、png……等)-源码程序/code/Src/Client/scwinlib/MSDib.cpp
//Download by http://www.NewXing.com /* * This file is part of the EMFexplorer projet. * Copyright (C) 2004 Smith Charles. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * Extension: for commercial use, apply the Equity Public License, which * adds to the normal terms of the GLPL a condition of donation to the author. * If you are interested in support for this source code, * contact Smith Charles <smith.charles@free.fr> for more information. */ #include "stdafx.h" #include "MSDib.h" #ifndef SC_USE_MSDIBCODE #error "Provide your implementation for DIBNumColors,..." #else //////////////////////////////////////////////////////////////////////////////////////// // (c) Microsoft, 1991-1998 / MSDN / DIBUTIL.C, DIB.C // /************************************************************************* * This function calculates the number of colors in the DIB's color table * by finding the bits per pixel for the DIB (whether Win3.0 or other-style * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256, * if 24, no colors in color table. * ************************************************************************/ WORD WINAPI DIBNumColors(LPBITMAPINFOHEADER lpbi) { WORD wBitCount; // DIB bit count /* If this is a Windows-style DIB, the number of colors in the * color table can be less than the number of bits per pixel * allows for (i.e. lpbi->biClrUsed can be set to some value). * If this is the case, return the appropriate value. */ if (IS_WIN30_DIB(lpbi)) { DWORD dwClrUsed; dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; if (dwClrUsed != 0) return (WORD)dwClrUsed; } /* Calculate the number of colors in the color table based on * the number of bits per pixel for the DIB. */ if (IS_WIN30_DIB(lpbi)) wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; else wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; /* return number of colors based on bits per pixel */ switch (wBitCount) { case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; } } /************************************************************************* * This function gets the size required to store the DIB's palette by * multiplying the number of colors by the size of an RGBQUAD (for a * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other- * style DIB). * ************************************************************************/ WORD WINAPI PaletteSize(LPBITMAPINFOHEADER lpbi) { /* calculate the size required by the palette */ if (IS_WIN30_DIB (lpbi)) return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD)); else return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE)); } // dib.c /**************************************************************************** * * * FUNCTION : DibFromBitmap() * * * * PURPOSE : Will create a global memory block in DIB format that * * represents the Device-dependent bitmap (DDB) passed in. * * * * RETURNS : A handle to the DIB * * * ****************************************************************************/ HANDLE DibFromBitmap(HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal) { BITMAP bm; BITMAPINFOHEADER bi; LPBITMAPINFOHEADER lpbi; DWORD dwLen; HANDLE hdib; HANDLE h; HDC hdc; if (!hbm) return NULL; if (hpal == NULL) hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); GetObject(hbm,sizeof(bm),(LPSTR)&bm); if (biBits == 0) biBits = bm.bmPlanes * bm.bmBitsPixel; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = biBits; bi.biCompression = biStyle; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; dwLen = bi.biSize + PaletteSize(&bi); hdc = GetDC(NULL); hpal = SelectPalette(hdc,hpal,FALSE); RealizePalette(hdc); hdib = GlobalAlloc(GHND,dwLen); if (!hdib) { SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return NULL; } lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib); *lpbi = bi; /* call GetDIBits with a NULL lpBits param, so it will calculate the * biSizeImage field for us */ GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight, NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); bi = *lpbi; GlobalUnlock(hdib); /* If the driver did not fill in the biSizeImage field, make one up */ if (bi.biSizeImage == 0) { bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight; if (biStyle != BI_RGB) bi.biSizeImage = (bi.biSizeImage * 3) / 2; } /* realloc the buffer big enough to hold all the bits */ dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage; if (h = GlobalReAlloc(hdib,dwLen,0)) hdib = h; else { GlobalFree(hdib); hdib = NULL; SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return hdib; } /* call GetDIBits with a NON-NULL lpBits param, and actualy get the * bits this time */ lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib); if (GetDIBits( hdc, hbm, 0, (WORD)bi.biHeight, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0) { GlobalUnlock(hdib); hdib = NULL; SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return NULL; } bi = *lpbi; GlobalUnlock(hdib); SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return hdib; } #endif // End of Microsoft code ////////////////////////////////////////////////////////////////////////////////////////////